package com.chaochis.springboottestdemo.service.impl;

import com.chaochis.springboottestdemo.config.reqResConfig.dispatcherConfig.CustomRequestWrapper;
import com.chaochis.springboottestdemo.constant.UserCacheConstant;
import com.chaochis.springboottestdemo.model.apiResultVo.ApiUser;
import com.chaochis.springboottestdemo.model.commonModel.LoginUserVo;
import com.chaochis.springboottestdemo.model.serviceModel.JwtToken;
import com.chaochis.springboottestdemo.model.serviceModel.RedisCacheUser;
import com.chaochis.springboottestdemo.service.CacheRedisLoginService;
import com.chaochis.springboottestdemo.util.ClientInfoUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Date;

@Service("cacheRedisLoginService")
public class CacheRedisLoginServiceImpl implements CacheRedisLoginService {

  private final RedisTemplate<String, Object> redisTemplate;

  public CacheRedisLoginServiceImpl(@Qualifier("redisJackJsonTemplate") RedisTemplate<String, Object> redisTemplate) {
    this.redisTemplate = redisTemplate;
  }

  @Override
  public void cacheLoginUserInfo(CustomRequestWrapper customRequestWrapper, JwtToken jwtToken, LoginUserVo loginUserVo) {
    System.out.println(jwtToken);
    var userName = loginUserVo.getUserVo().getUserName();
    var token = jwtToken.getToken();
    var clientInfo = ClientInfoUtil.get(customRequestWrapper);
    var tokenMd5 = DigestUtils.md5Hex(token);
    var redisCacheUser = new RedisCacheUser();
    redisCacheUser.setClientInfo(clientInfo);
    redisCacheUser.setApiUser(new ApiUser());
    BeanUtils.copyProperties(loginUserVo.getUserVo(), redisCacheUser.getApiUser());
    this.deleteUserAllCache(userName);
    var duration = Duration.ofMillis(jwtToken.getExpireDate().getTime() - new Date().getTime());
    // 保存tokenMd5
    String loginTokenRedisKey = String.format(UserCacheConstant.LOGIN_TOKEN, tokenMd5);
    this.redisTemplate.opsForValue().set(loginTokenRedisKey, jwtToken, duration);
    // 保存用户及设备信息
    String loginUserNameKey = String.format(UserCacheConstant.LOGIN_USER, userName);
    this.redisTemplate.opsForValue().set(loginUserNameKey, redisCacheUser, duration);
    // 保存通过
    String loginUserTokenKey = String.format(UserCacheConstant.LOGIN_USER_TOKEN, userName, tokenMd5);
    this.redisTemplate.opsForValue().set(loginUserTokenKey, loginTokenRedisKey, duration);
  }

  public void deleteUserAllCache(String username) {
    var userTokenMd5Set = this.redisTemplate.keys(String.format(UserCacheConstant.LOGIN_USER_ALL_TOKEN, username));
    assert userTokenMd5Set != null;
    if(userTokenMd5Set.isEmpty()){
      return ;
    }
    var tokenMd5List = this.redisTemplate.opsForValue().multiGet(userTokenMd5Set);
    assert tokenMd5List != null;
    for(var item : tokenMd5List) {
      this.redisTemplate.delete((String) item);
    }
    this.redisTemplate.delete(userTokenMd5Set);
    this.redisTemplate.delete(String.format(UserCacheConstant.LOGIN_USER, username));
  }
}
